package myauctioneer;

import java.io.File;
import java.io.FileInputStream;
import java.util.Properties;
import java.sql.Connection;
import java.sql.DriverManager;

import java.util.logging.FileHandler;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.logging.SimpleFormatter;

import java.util.Date;
import java.text.SimpleDateFormat;

import org.stringtemplate.v4.ST;
import org.stringtemplate.v4.STGroup;
import org.stringtemplate.v4.STGroupDir;

public final class App
{
	private String baseDir;
	private String baseUrl;
	private String serverTime;
	private STGroup stGroup;
	private Properties prop;
	private Connection conn;
	private Logger logger;

	/**
	 * The constructor.
	 *
	 * @param baseDir Root directrory
	 * @param baseUrl Base url, where the app is available
	 */
	public App(String baseDir, String baseUrl)
		throws Exception
	{
		this.baseDir = baseDir;
		this.baseUrl = baseUrl;		
		this.serverTime = new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss z [Z]").format(new Date());

		/*
		 * Initialize StringTemplate
		 */
		this.stGroup = new STGroupDir(baseDir + "/template", '$', '$');

		/*
		 * Initialize Properties
		 */
		File local = new File(baseDir + "/local.properties");
		File config = new File(baseDir + "/config.properties");

		Properties propDefault = new Properties();
		propDefault.load(new FileInputStream(config));

		this.prop = new Properties(propDefault);

		if(local.exists())
			this.prop.load(new FileInputStream(local));

		/*
		 * Initialize Database Connection
		 */
		Class.forName("oracle.jdbc.driver.OracleDriver");

		this.conn = DriverManager.getConnection(
			this.getProperty("db.url"),
			this.getProperty("db.user"),
			this.getProperty("db.password")
		);

		/*
		 * Initialize Logger.
		 *
		 * @todo log level should be configurable via properties mechanism.
		 */
		this.logger = Logger.getLogger("myauctioneer");
		this.logger.setLevel(Level.INFO);
		FileHandler file = new FileHandler(baseDir + "/var/log.txt", true);
		file.setFormatter(new SimpleFormatter());
		this.logger.addHandler(file);
	}

	public String getBaseDir()
	{
		return this.baseDir;
	}

	public String getBaseUrl()
	{
		return this.baseUrl;
	}

	public Connection getDb()
	{
		return this.conn;
	}

	/**
	 * Get the Logger object.
	 * It is configured to write to var/log.txt file.
	 */
	public Logger getLogger()
	{
		return this.logger;
	}

	/**
	 * Return a named configuration property.
	 *
	 * @param name
	 */
	public String getProperty(String name)
	{
		return this.prop.getProperty(name);
	}

	/**
	 * Return a named template instance.
	 *
	 * @param name
	 */
	public ST getTemplate(String name)
	{
		return this.stGroup.getInstanceOf(name).add("app", this);
	}

	/**
	 * Debugging.
	 */
	public String getHashCode()
	{
		return String.valueOf(this.hashCode());
	}
	
	/**
	 * Webserver startup-time
	 */
	public String getServerTime() {
		return serverTime;
	}
}
